﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public partial class Sermons_RSSManager : System.Web.UI.Page
{

    // xml filename
    private readonly string _FILENAME = "cantonese.xml";


    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            XDocument xdoc = XDocument.Load(Server.MapPath(_FILENAME));
            var items = xdoc.Root.Descendants("item");
            this.rptrItems.DataSource = items;
            this.rptrItems.DataBind();

            // drop downs on Add form
            this.InitDropDownList(this.ddlDay, 1, 31, "DD");
            this.InitDropDownList(this.ddlMonth, 1, 12, "MM");
            this.InitDropDownList(this.ddlYear, 2008, DateTime.Now.Year, "YYYY");
            this.InitDropDownList(this.ddlHours, 0, 10, null);
            this.InitDropDownList(this.ddlMinutes, 0, 59, null);
            this.InitDropDownList(this.ddlSeconds, 0, 59, null);
            this.InitDropDownList(this.ddlMB, 0, 100, null, false);
            this.InitDropDownList(this.ddlMBtenths, 0, 9, null, false);
        }
    }

    /// <summary>
    /// Initialise the drop down list
    /// </summary>
    /// <param name="ddl"></param>
    /// <param name="minValue"></param>
    /// <param name="maxValue"></param>
    private void InitDropDownList(DropDownList ddl, int minValue, int maxValue, string initText)
    {
        this.InitDropDownList(ddl, minValue, maxValue, initText, true);
    }

    private void InitDropDownList(DropDownList ddl, int minValue, int maxValue, string initText, bool padValues)
    {
        for (int i = minValue; i <= maxValue; i++)
        {
            ListItem li = (padValues) ? new ListItem(i.ToString().PadLeft(2, '0'), i.ToString()) : new ListItem(i.ToString(), i.ToString());
            ddl.Items.Add(li);
        }

        if (initText != null)
            ddl.Items.Insert(0, new ListItem(initText, ""));
    }

    /// <summary>
    /// Add a new sermon item
    /// </summary>
    private void AddNewSermonItem()
    {
        // collect the values
        string title = this.txtTitle.Text;
        DateTime dateOfTalk = new DateTime(Int32.Parse(this.ddlYear.SelectedValue), Int32.Parse(this.ddlMonth.SelectedValue), Int32.Parse(this.ddlDay.SelectedValue));
        string speaker = this.txtSpeaker.Text;
        string passage = this.txtPassage.Text;
        string url = this.txtLink.Text;
        string sermonLength = this.ddlHours.SelectedValue + ":" + this.ddlMinutes.SelectedValue + ":" + this.ddlSeconds.SelectedValue;
        decimal filesize = decimal.Parse(this.ddlMB.SelectedValue + "." + this.ddlMBtenths.SelectedValue) * 1024 * 1024; // bytes
        
        // open xml doc
        XDocument xdoc = XDocument.Load(Server.MapPath(_FILENAME));

        // create element
        XElement newElement = new XElement("item",
                                new XElement("title", title),
                                new XElement("link", url),
                                new XElement("comments", url),
                                new XElement("{http://www.itunes.com/dtds/podcast-1.0.dtd}author", speaker),
                                new XElement("{http://purl.org/dc/elements/1.1/}creator", speaker),
                                new XElement("description", passage),
                                new XElement("pubDate", dateOfTalk.ToUniversalTime().ToString("r", null)),
                                new XElement("{http://www.itunes.com/dtds/podcast-1.0.dtd}subtitle", ""),
                                new XElement("{http://www.itunes.com/dtds/podcast-1.0.dtd}summary", title + " - " + passage),
                                new XElement("{http://www.itunes.com/dtds/podcast-1.0.dtd}keywords", ""),
                                new XElement("{http://www.itunes.com/dtds/podcast-1.0.dtd}duration", sermonLength),
                                new XElement("enclosure",
                                    new XAttribute("url", url),
                                    new XAttribute("length", (decimal.ToInt32(filesize)).ToString()),
                                    new XAttribute("type", "audio/mpeg")),
                                new XElement("guid", url),
                                new XElement("{http://www.itunes.com/dtds/podcast-1.0.dtd}explicit", "no"));

        // local 'ttl' element, and append new element after it
        XElement ttl = xdoc.Descendants("ttl").Single();
        ttl.AddAfterSelf(newElement);
        xdoc.Save(Server.MapPath(_FILENAME));

        // ack screen
        this.litConfirmMsg.Text = "Item added";
        this.mvMain.SetActiveView(this.viewAcknowledgement);
    }


    /// <summary>
    /// Convert bytes to megabytes
    /// </summary>
    /// <param name="bytes"></param>
    /// <param name="mb"></param>
    /// <param name="mbTenths"></param>
    private void BytesToMegaBytes(int bytes, out int mb, out int mbTenths)
    {
        int remainder;
        mb = Math.DivRem(bytes, 1024 * 1024, out remainder);
        mbTenths = decimal.ToInt32(decimal.Round(decimal.Divide(remainder * 10, (1024 * 1024))));
    }



    #region Events

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        this.btnCreate.Click += new EventHandler(btnCreate_Click);
        this.rptrItems.ItemDataBound += new RepeaterItemEventHandler(rptrItems_ItemDataBound);
        this.rptrItems.ItemCommand += new RepeaterCommandEventHandler(rptrItems_ItemCommand);
        this.valDateOfTalk.ServerValidate += new ServerValidateEventHandler(valDateOfTalk_ServerValidate);
    }

    void btnCreate_Click(object sender, EventArgs e)
    {
        Page.Validate("add");
        if (Page.IsValid)
        {
            this.AddNewSermonItem();
        }
    }

    void rptrItems_ItemCommand(object source, RepeaterCommandEventArgs e)
    {
        XDocument xdoc = XDocument.Load(Server.MapPath(_FILENAME));
        RepeaterItem ri = e.Item;
        
        List<XElement> items = xdoc.Root.Descendants("item").ToList();
        XElement item = items[ri.ItemIndex];

        if (e.CommandName == "Update")
        {            
            Page.Validate("update");
            if (Page.IsValid)
            {
                TextBox txtTitle = (TextBox)ri.FindControl("txtTitle");
                TextBox txtSpeaker = (TextBox)ri.FindControl("txtSpeaker");
                TextBox txtPassage = (TextBox)ri.FindControl("txtPassage");
                TextBox txtLink = (TextBox)ri.FindControl("txtLink");
                Label lblUpdated = (Label)ri.FindControl("lblUpdated");
                DropDownList ddlYear = (DropDownList)ri.FindControl("ddlYear");
                DropDownList ddlMonth = (DropDownList)ri.FindControl("ddlMonth");
                DropDownList ddlDay = (DropDownList)ri.FindControl("ddlDay");
                DropDownList ddlMB = (DropDownList)ri.FindControl("ddlMB");
                DropDownList ddlMBtenths = (DropDownList)ri.FindControl("ddlMBtenths");
                DropDownList ddlHours = (DropDownList)ri.FindControl("ddlHours");
                DropDownList ddlMinutes = (DropDownList)ri.FindControl("ddlMinutes");
                DropDownList ddlSeconds = (DropDownList)ri.FindControl("ddlSeconds");

                DateTime dateOfTalk = new DateTime(Int32.Parse(ddlYear.SelectedValue), Int32.Parse(ddlMonth.SelectedValue), Int32.Parse(ddlDay.SelectedValue));
                decimal filesize = decimal.Parse(ddlMB.SelectedValue + "." + ddlMBtenths.SelectedValue) * 1024 * 1024; // bytes
                string sermonLength = ddlHours.SelectedValue + ":" + ddlMinutes.SelectedValue + ":" + ddlSeconds.SelectedValue;

                item.Element("title").Value = txtTitle.Text;
                item.Element("link").Value = txtLink.Text;
                item.Element("comments").Value = txtLink.Text;
                item.Element("{http://www.itunes.com/dtds/podcast-1.0.dtd}author").Value = txtSpeaker.Text;
                item.Element("{http://purl.org/dc/elements/1.1/}creator").Value = txtSpeaker.Text;
                item.Element("description").Value = txtPassage.Text;
                item.Element("pubDate").Value = dateOfTalk.ToUniversalTime().ToString("r", null);
                item.Element("{http://www.itunes.com/dtds/podcast-1.0.dtd}summary").Value = txtTitle.Text + " - " + txtPassage.Text;
                item.Element("{http://www.itunes.com/dtds/podcast-1.0.dtd}duration").Value = sermonLength;
                item.Element("guid").Value = txtLink.Text;
                item.Element("enclosure").Attribute("url").Value = txtLink.Text;
                item.Element("enclosure").Attribute("length").Value = (decimal.ToInt32(filesize)).ToString();

                // save
                xdoc.Save(Server.MapPath(_FILENAME));

                // confirm message
                lblUpdated.Text = "Updated";
            }
        }
        else if (e.CommandName == "Delete")
        {
            // remove and save
            item.Remove();
            xdoc.Save(Server.MapPath(_FILENAME));

            // change view
            this.mvMain.SetActiveView(this.viewAcknowledgement);

            // confirm message
            this.litConfirmMsg.Text = "Item deleted";
        }
    }

    void rptrItems_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            XElement element = e.Item.DataItem as XElement;
            TextBox txtBox;
            foreach (var elementItem in element.Descendants())
            {
                switch (elementItem.Name.ToString())
                {
                    case "title":
                        txtBox = (TextBox)e.Item.FindControl("txtTitle");
                        txtBox.Text = elementItem.Value;
                        break;
                    case "pubDate":
                        DropDownList ddlDay = (DropDownList)e.Item.FindControl("ddlDay");
                        DropDownList ddlMonth = (DropDownList)e.Item.FindControl("ddlMonth");
                        DropDownList ddlYear = (DropDownList)e.Item.FindControl("ddlYear");
                        this.InitDropDownList(ddlDay, 1, 31, "DD");
                        this.InitDropDownList(ddlMonth, 1, 12, "MM");
                        this.InitDropDownList(ddlYear, 2008, DateTime.Now.Year, "YYYY");

                        DateTime dateOfTalk = DateTime.ParseExact(elementItem.Value, "r", null).ToLocalTime();
                        ddlDay.SelectedValue = dateOfTalk.Day.ToString();
                        ddlMonth.SelectedValue = dateOfTalk.Month.ToString();
                        ddlYear.SelectedValue = dateOfTalk.Year.ToString();

                        break;
                    case "{http://purl.org/dc/elements/1.1/}creator":
                        txtBox = (TextBox)e.Item.FindControl("txtSpeaker");
                        txtBox.Text = elementItem.Value;
                        break;
                    case "link":
                        txtBox = (TextBox)e.Item.FindControl("txtLink");
                        txtBox.Text = elementItem.Value;
                        break;
                    case "description":
                        txtBox = (TextBox)e.Item.FindControl("txtPassage");
                        txtBox.Text = elementItem.Value;
                        break;
                    case "{http://www.itunes.com/dtds/podcast-1.0.dtd}duration":
                        DropDownList ddlHours = (DropDownList)e.Item.FindControl("ddlHours");
                        DropDownList ddlMinutes = (DropDownList)e.Item.FindControl("ddlMinutes");
                        DropDownList ddlSeconds = (DropDownList)e.Item.FindControl("ddlSeconds");
                        this.InitDropDownList(ddlHours, 0, 10, null);
                        this.InitDropDownList(ddlMinutes, 0, 59, null);
                        this.InitDropDownList(ddlSeconds, 0, 59, null);
                        
                        string[] duration = elementItem.Value.Split(':');
                        ddlHours.SelectedValue = duration[0];
                        ddlMinutes.SelectedValue = duration[1];
                        ddlSeconds.SelectedValue = duration[2];

                        break;
                    case "enclosure":
                        DropDownList ddlMB = (DropDownList)e.Item.FindControl("ddlMB");
                        DropDownList ddlMBtenths = (DropDownList)e.Item.FindControl("ddlMBtenths");
                        this.InitDropDownList(ddlMB, 0, 100, null, false);
                        this.InitDropDownList(ddlMBtenths, 0, 9, null, false);

                        int bytes = Int32.Parse(elementItem.Attribute("length").Value);
                        int mb, mbTenths;
                        this.BytesToMegaBytes(bytes, out mb, out mbTenths);
                        ddlMB.SelectedValue = mb.ToString();
                        ddlMBtenths.SelectedValue = mbTenths.ToString();
                        
                        break;
                }
            }
        }
    }


    protected void valDateOfTalk_ServerValidate(object source, ServerValidateEventArgs args)
    {
        CustomValidator val = (CustomValidator)source;
        DropDownList ddlDay = (DropDownList)val.Parent.FindControl("ddlDay");
        DropDownList ddlMonth = (DropDownList)val.Parent.FindControl("ddlMonth");
        DropDownList ddlYear = (DropDownList)val.Parent.FindControl("ddlYear");

        try
        {
            DateTime dateOfTalk = new DateTime(Int32.Parse(ddlYear.SelectedValue), Int32.Parse(ddlMonth.SelectedValue), Int32.Parse(ddlDay.SelectedValue));
            args.IsValid = true;
        }
        catch
        {
            args.IsValid = false;
        }
    }


    #endregion


}
